package com.denlaku.longan.controller.impl;

import com.denlaku.longan.anno.Audit;
import com.denlaku.longan.anno.VarBy;
import com.denlaku.longan.audit.AuditVariables;
import com.denlaku.longan.controller.TenantController;
import com.denlaku.longan.http.Resp;
import com.denlaku.longan.http.Return;
import com.denlaku.longan.service.TenantService;
import com.denlaku.longan.service.UserService;
import com.denlaku.longan.vo.PageBy;
import com.denlaku.longan.vo.Tenant;
import com.denlaku.longan.vo.User;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author tianx
 */
@RestController
public class TenantControllerImpl implements TenantController {
    @Autowired
    private TenantService tenantService;

    @Autowired
    private UserService userService;

    @VarBy
    @Override
    public Return<List<Tenant>> pageList(Tenant tenant, PageBy pageBy) {
        PageHelper.startPage(pageBy.getPage(), pageBy.getSize());
        List<Tenant> list = tenantService.list(tenant);
        Set<Long> ownerIds = list.stream().map(Tenant::getOwner).collect(Collectors.toSet());
        Map<Long, User> userMap = userService.listBaseInfoMap(ownerIds);
        return Resp.success(list).setUmap(userMap);
    }

    @Override
    public Return<List<Tenant>> list(Tenant tenant) {
        List<Tenant> list = tenantService.list(tenant);
        return Resp.success(list);
    }

    @Override
    public Return<Tenant> get(Long id) {
        Tenant tenant = tenantService.get(id);
        return Resp.success(tenant);
    }

    @Override
    @Audit(module = "Tenant", operation = "audit.operation.addTenant", message = "add tenant: {#tenant.code}")
    public Return<Long> add(@RequestBody Tenant tenant) {
        tenantService.add(tenant);
        return Resp.success(tenant.getId());
    }

    @Override
    @Audit(module = "Tenant", operation = "audit.operation.updateTenant", message = "update tenant: {#tenant.code}")
    public Return<Void> update(@RequestBody Tenant tenant) {
        tenantService.update(tenant);
        return Resp.success();
    }

    @Override
    @Audit(module = "Tenant", operation = "audit.operation.deleteTenant", message = "delete tenant: {#code}")
    public Return<Void> delete(Long id) {
        setVariable(id);
        tenantService.delete(id);
        return Resp.success();
    }

    private void setVariable(Long id) {
        Tenant tenant = tenantService.get(id);
        String code = Optional.ofNullable(tenant).map(Tenant::getCode).orElse(String.valueOf(id));
        AuditVariables.set("code", code);
    }

    @Override
    @Audit(module = "Tenant", operation = "audit.operation.disabledTenant", message = "disabled tenant: {#code}")
    public Return<Void> disabled(Long id) {
        setVariable(id);
        tenantService.disabled(id);
        return Resp.success();
    }

    @Override
    @Audit(module = "Tenant", operation = "audit.operation.enabledTenant", message = "enabled tenant: {#code}")
    public Return<Void> enabled(Long id) {
        setVariable(id);
        tenantService.enabled(id);
        return Resp.success();
    }

}
